package com.olap.starter.util.sql.jsqlparser;

import com.olap.starter.util.StringUtils;
import com.olap.starter.util.sql.TableNameAndField;
import com.olap.starter.util.sql.jsqlparser.NormalSqlStructureDto;
import net.sf.jsqlparser.JSQLParserException;
import net.sf.jsqlparser.expression.*;
import net.sf.jsqlparser.parser.CCJSqlParserManager;
import net.sf.jsqlparser.parser.CCJSqlParserUtil;
import net.sf.jsqlparser.parser.SimpleNode;
import net.sf.jsqlparser.schema.Column;
import net.sf.jsqlparser.schema.Table;
import net.sf.jsqlparser.statement.Statement;
import net.sf.jsqlparser.statement.select.*;
import net.sf.jsqlparser.util.TablesNamesFinder;
import org.springframework.util.CollectionUtils;

import java.io.StringReader;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class JsqlParserUtil {
    public static void main(String[] args) throws JSQLParserException {
        // 输入一个sql
        String sql1 = "select t11.*,t1.* \n" +
                "from original_data.edu_college_student As t1\n" +
                "JOIN original_data.edu_college_test_score t11\n" +
                "on t1.s_id = t11.s_id \n" +
                "where 1=1 \n";

      /*  String sql = "select t2.te tt," +
                "t1.te2," +
                "t3.te3," +
                "sum(`t1.add`) as t5," +
                "SUM(CASE WHEN elm_code = '030' THEN elm_act ELSE '0' END) AS P " +
                "from table1 as t1" +
                " left join table2 t2 on t1.id=t2.parentId" +
                " left join pe_Tqmts25 t3 on t1.id = t3.parentId";*/
        String sql = "select t2.te tt," +
                "t1.te2," +
                "t3.te3," +
                "sum(`t1.add`) as t5," +
                "SUM(CASE WHEN elm_code = '030' THEN elm_act ELSE '0' END) AS P " +
                "from table1 as t1" +
                " left join table2 t2 on t1.id=t2.parentId" +
                " left join pe_Tqmts25 t3 on t1.id = t3.parentId where t1.id = (select * from tt2 where ttt = 3)";
        String sql2 = "with v_0001 as\n" +
                " (select 产出材料, sum(wt) 产出重量\n" +
                "    from (select substr(mat_no, 0, 11) || '000' 产出材料, sum(mat_act_wt) wt\n" +
                "            from tmmhp01\n" +
                "           group by substr(mat_no, 0, 11) || '000'\n" +
                "          union all\n" +
                "          select substr(mat_no, 0, 11) || '000', sum(mat_act_wt)\n" +
                "            from hmmhp01\n" +
                "           where MAT_STATUS in ('36', '37','46')\n" +
                "              or COMPLEX_DECIDE_CODE = '4'\n" +
                "              or trim(HOLD_REMARK) = '轧废'\n" +
                "           group by substr(mat_no, 0, 11) || '000')\n" +
                "   group by 产出材料),\n" +
                "V_tmhp01 as\n" +
                " (select STEEL_GRADE          计划牌号,\n" +
                "         MAT_NO           大板号,\n" +
                "         SHIFT_GROUP 班组,\n" +
                "         SLAB_THICKNESS       坯料厚度,\n" +
                "         SLAB_WEIGHT   板坯重量,\n" +
                "         产出重量\n" +
                "    from tmmhp21\n" +
                "    left join v_0001\n" +
                "      on mat_no = 产出材料\n" +
                "   where mat_no <> ' '\n" +
                "     and decode(TIME_ROLLING_END,\n" +
                "                '00000000000000',\n" +
                "                TIME_ROLLING_END,\n" +
                "                TIME_ROLLING_END) >= '2025-02-01' || '00:00:00'\n" +
                "     and decode(TIME_ROLLING_END,\n" +
                "                '00000000000000',\n" +
                "                TIME_ROLLING_END,\n" +
                "                TIME_ROLLING_END) <= '2025-02-05' || '23:59:59'),\n" +
                "V_tmhp02 as\n" +
                " (select START_ORDER_NO 原始合同号,\n" +
                "         t.MAT_NO 材料号,\n" +
                "         SG_SIGN 实际牌号,\n" +
                "         PSC 产品规范,\n" +
                "         OLD_PSC 原产品规范,\n" +
                "         ST_NO 内部钢种,\n" +
                "         MAT_THICK 材料厚度,\n" +
                "         MAT_ACT_THICK 实际厚度,\n" +
                "         DEFECT_CODE 缺陷代码,\n" +
                "         MAT_ACT_WT 重量,\n" +
                "         COMPLEX_DECIDE_CODE 综判码,\n" +
                "         COMPLEX_DECIDE_TIME 综判时间,\n" +
                "         mat_act_width 材料宽度,\n" +
                "         Mat_Act_Len 材料长度,\n" +
                "         WITH_SIDE_FLAG 切边标记,\n" +
                "         TRIM_TYPE 边缘状态,\n" +
                "         HOLD_REMARK 封锁注释,\n" +
                "         V_tmhp01.*,\n" +
                "         case\n" +
                "           when length(t4.mat_no) > 2 then\n" +
                "            '热处理'\n" +
                "           else\n" +
                "            '主线'\n" +
                "         end 产线\n" +
                "    from tmmhp01 t\n" +
                "    left join (select mat_no from tmmht01 group by mat_no) t4\n" +
                "      on t.mat_no = t4.mat_no\n" +
                "   inner join V_tmhp01\n" +
                "      on substr(t.mat_no, 0, 11) = substr(大板号, 0, 11)\n" +
                "     and ((SPRAY_FLAG = '1' and PROD_STATUS in ('XB','RB')) or\n" +
                "          COMPLEX_DECIDE_CODE = '4')\n" +
                "  union all\n" +
                "  select START_ORDER_NO 原始合同号,\n" +
                "         t.MAT_NO 材料号,\n" +
                "         SG_SIGN 实际牌号,\n" +
                "         PSC 产品规范,\n" +
                "         OLD_PSC 原产品规范,\n" +
                "         ST_NO 内部钢种,\n" +
                "         MAT_THICK 材料厚度,\n" +
                "         MAT_ACT_THICK 实际厚度,\n" +
                "         DEFECT_CODE 缺陷代码,\n" +
                "         MAT_ACT_WT 重量,\n" +
                "         COMPLEX_DECIDE_CODE 综判码,\n" +
                "         COMPLEX_DECIDE_TIME 综判时间,\n" +
                "         mat_act_width 材料宽度,\n" +
                "         Mat_Act_Len 材料长度,\n" +
                "         WITH_SIDE_FLAG 切边标记,\n" +
                "         TRIM_TYPE 边缘状态,\n" +
                "         HOLD_REMARK 封锁注释,\n" +
                "         V_tmhp01.*,\n" +
                "         case\n" +
                "           when length(t4.mat_no) > 2 then\n" +
                "            '热处理'\n" +
                "           else\n" +
                "            '主线'\n" +
                "         end 产线\n" +
                "    from hmmhp01 t\n" +
                "    left join (select mat_no from tmmht01 group by mat_no) t4\n" +
                "      on t.mat_no = t4.mat_no\n" +
                "   inner join V_tmhp01\n" +
                "      on substr(t.mat_no, 0, 11) = substr(大板号, 0, 11)\n" +
                "     and (MAT_STATUS in ('36','37','46') or COMPLEX_DECIDE_CODE = '4' or\n" +
                "          trim(HOLD_REMARK) = '轧废')),\n" +
                "V_tmhp76 as\n" +
                " (select V_tmhp02.*,\n" +
                "         MAT_NO           小板号,\n" +
                "         AVAILABLE_MATERIAL1_DISTINGUISH     可利用材区分,\n" +
                "         AVAILABLE_MATERIAL1_REASON_CODE 可用材代码,\n" +
                "         AVAILABLE_MATERIAL1_WT         可用材重量,\n" +
                "         EXCESSIVE_WASTE_REASON_CODE1   多余废品1代码,\n" +
                "         EXCESSIVE_WASTE_WT1     多余废品1重量,\n" +
                "         EXCESSIVE_WASTE_REASON_CODE2 多余废品2代码,\n" +
                "         EXCESSIVE_WASTE_WT2   多余废品2重量\n" +
                "    from TMMHP26\n" +
                "   right join V_tmhp02\n" +
                "      on decode(substr(材料号, 12, 3),\n" +
                "                '000',\n" +
                "                substr(材料号, 1, 11) || '100',\n" +
                "                材料号) = decode(substr(MAT_NO, 12, 3),\n" +
                "                              '000',\n" +
                "                              substr(MAT_NO, 1, 11) || '100',\n" +
                "                              MAT_NO)),\n" +
                "V_tmrp04 as\n" +
                " (select V_tmhp02.*,\n" +
                "        substr(PSC, 3, 7) 标准牌号代码,\n" +
                "         ORDER_NO 合同号,\n" +
                "         ORDER_THICK 合同厚度,\n" +
                "         ORDER_WIDTH 合同宽度,\n" +
                "         ORDER_MIN_LEN 合同长下限,\n" +
                "         ORDER_MAX_LEN 合同长上限,\n" +
                "         ORDER_MIN_WIDTH 合同宽下限,\n" +
                "         ORDER_MAX_LEN_WIDTH 合同宽上限,\n" +
                "         ORDER_SPECIAL,substr(PSC, 11, 1) 厚度公差类别\n" +
                "    from V_tmhp02\n" +
                "    left join tom01\n" +
                "      on 原始合同号 = ORDER_NO\n" +
                "   where prod_class_code = 'H'),\n" +
                "V_tmrp00 as\n" +
                " (select V_tmhp76.*,\n" +
                "         substr(PSC, 3, 7) 标准牌号代码,\n" +
                "         ORDER_NO 合同号,\n" +
                "         ORDER_THICK 合同厚度,\n" +
                "         ORDER_WIDTH 合同宽度,\n" +
                "         ORDER_MIN_LEN 合同长下限,\n" +
                "         ORDER_MAX_LEN 合同长上限,\n" +
                "         ORDER_MIN_WIDTH 合同宽下限,\n" +
                "         ORDER_MAX_LEN_WIDTH 合同宽上限,\n" +
                "         ORDER_SPECIAL,substr(PSC, 11, 1) 厚度公差类别\n" +
                "    from V_tmhp76\n" +
                "    left join tom01\n" +
                "      on 原始合同号 = ORDER_NO\n" +
                "   where prod_class_code = 'H'),\n" +
                "V_tmrp01 as\n" +
                " (select * from V_tmrp00 where 可用材重量 != 0),\n" +
                "V_tmrp02 as\n" +
                " (select * from V_tmrp00 where 多余废品1重量 != 0),\n" +
                "V_tmrp03 as\n" +
                " (select * from V_tmrp00 where 多余废品2重量 != 0),\n" +
                "V_tmrpa1 as\n" +
                " (select 材料号,\n" +
                "         产线,\n" +
                "         计划品 as 一次命中量,\n" +
                "         计划牌号,\n" +
                "         实际牌号,\n" +
                "         ST_NO_DESC 内部钢种,\n" +
                "         班组,\n" +
                "         坯料厚度,\n" +
                "         材料厚度,\n" +
                "         实际厚度,\n" +
                "         材料宽度,\n" +
                "         材料长度,\n" +
                "         切边标记,\n" +
                "         边缘状态,\n" +
                "         定尺类型,\n" +
                "         标准牌号代码,\n" +
                "         厚度公差类别,\n" +
                "         大板号,\n" +
                "         板坯重量,\n" +
                "         缺陷代码 代码,\n" +
                "         (select code_desc_2_content\n" +
                "            from tep0002\n" +
                "           where code_class = 'M037'\n" +
                "             and code = 缺陷代码) 缺陷代码,\n" +
                "         计划品 + 非计划品 + 利用板量 + 利用小板量 + 短尺板量 + 轧制改判量 + 热处理改判量 + 钢质改判量 + 性能改判量 + 轧废废品 + 轧制废品 + 定尺废品 +\n" +
                "         热处理废品 + 合同变更改判量 检验量,\n" +
                "         计划品 + 非计划品 + 利用板量 + 利用小板量 + 短尺板量 + 轧制改判量 + 热处理改判量 + 钢质改判量 + 性能改判量 +\n" +
                "         合同变更改判量 合格量,\n" +
                "         计划品 + 非计划品 + 轧制改判量 + 热处理改判量 + 钢质改判量 + 性能改判量 + 合同变更改判量 正板量,\n" +
                "         计划品 + 钢质改判量＋钢质协议量＋定尺协议量 + 合同变更量 + 合同变更改判量 定尺量,\n" +
                "         计划品,\n" +
                "         非计划品,\n" +
                "         厚度非计划品,\n" +
                "         宽度非计划品,\n" +
                "         长度非计划品,\n" +
                "         轧制协议量,\n" +
                "         热处理协议量,\n" +
                "         钢质协议量,\n" +
                "         定尺协议量,\n" +
                "         性能协议量,\n" +
                "         合同变更量,\n" +
                "         合同变更改判量,\n" +
                "         利用板量 + 利用小板量 + 短尺板量 协议量,\n" +
                "         轧制改判量,\n" +
                "         热处理改判量,\n" +
                "         钢质改判量,\n" +
                "         性能改判量,\n" +
                "         轧制改判量 + 热处理改判量 + 钢质改判量 + 性能改判量 + 合同变更改判量 改判量,\n" +
                "         轧制废品,\n" +
                "         热处理废品,\n" +
                "         钢质废品,\n" +
                "         定尺废品,\n" +
                "         轧废废品,\n" +
                "         轧废废品 + 多余废品量1 + 多余废品量2 废品量,\n" +
                "         利用板量,\n" +
                "         利用小板量,\n" +
                "         短尺板量,\n" +
                "         多余废品量1,\n" +
                "         多余废品量2,\n" +
                "         产出重量,\n" +
                "         负偏差块数,\n" +
                "         正偏差块数,\n" +
                "         块数合计,\n" +
                "         负偏差和,\n" +
                "         case\n" +
                "           when substr(缺陷代码, 0, 1) = 'I' then\n" +
                "            (计划品 + 轧制协议量 + 轧制改判量 + 轧废废品)\n" +
                "           else\n" +
                "            (计划品 + 非计划品 + 轧制协议量 + 轧制改判量 + 轧废废品)\n" +
                "         end 一次命中率分母\n" +
                "    from (select 材料号,\n" +
                "                 产线,\n" +
                "                 计划牌号,\n" +
                "                 实际牌号,\n" +
                "                 内部钢种,\n" +
                "                 班组,\n" +
                "                 坯料厚度,\n" +
                "                 材料厚度,\n" +
                "                 实际厚度,\n" +
                "                 材料宽度,\n" +
                "                 材料长度,\n" +
                "                 切边标记,\n" +
                "                 边缘状态,\n" +
                "                 标准牌号代码,\n" +
                "                 厚度公差类别,\n" +
                "                 大板号,\n" +
                "                 板坯重量,\n" +
                "                 缺陷代码,\n" +
                "                 case\n" +
                "                   when 综判码 = '4' and 综判时间 != ' ' then\n" +
                "                    重量\n" +
                "                   else\n" +
                "                    0\n" +
                "                 end 利用板量,\n" +
                "                 0 利用小板量,\n" +
                "                 0 短尺板量,\n" +
                "                 case\n" +
                "                   when 综判码 = '4' and 综判时间 != ' ' and substr(缺陷代码, 0, 1) = 'I' then\n" +
                "                    重量\n" +
                "                   else\n" +
                "                    0\n" +
                "                 end 钢质协议量,\n" +
                "                 case\n" +
                "                   when 综判码 = '4' and 综判时间 != ' ' and 缺陷代码 != 'H800' and\n" +
                "                        (substr(缺陷代码, 0, 1) = 'H' or substr(缺陷代码, 0, 1) = 'K') then\n" +
                "                    重量\n" +
                "                   else\n" +
                "                    0\n" +
                "                 end 轧制协议量,\n" +
                "                 case\n" +
                "                   when 综判码 = '4' and 综判时间 != ' ' and substr(缺陷代码, 0, 1) = 'L' then\n" +
                "                    重量\n" +
                "                   else\n" +
                "                    0\n" +
                "                 end 热处理协议量,\n" +
                "                 case\n" +
                "                   when 综判码 = '4' and 综判时间 != ' ' and\n" +
                "                        (缺陷代码 = 'H800' or 缺陷代码 = '@@') then\n" +
                "                    重量\n" +
                "                   else\n" +
                "                    0\n" +
                "                 end 性能协议量,\n" +
                "                 0 钢质废品,\n" +
                "                 0 轧制废品,\n" +
                "                 0 热处理废品,\n" +
                "                 0 多余废品量1,\n" +
                "                 0 多余废品量2,\n" +
                "                 case\n" +
                "                   when 综判码 != '4' and 产品规范 != 原产品规范 and 原产品规范 != ' ' and\n" +
                "                        substr(缺陷代码, 0, 1) = 'I' then\n" +
                "                    重量\n" +
                "                   else\n" +
                "                    0\n" +
                "                 end 钢质改判量,\n" +
                "                 case\n" +
                "                   when 综判码 != '4' and 产品规范 != 原产品规范 and 原产品规范 != ' ' and\n" +
                "                        ((substr(缺陷代码, 0, 1) = 'H' and 缺陷代码 <> 'H700' and\n" +
                "                        缺陷代码 <> 'H800') or substr(缺陷代码, 0, 1) = 'K') then\n" +
                "                    重量\n" +
                "                   else\n" +
                "                    0\n" +
                "                 end 轧制改判量,\n" +
                "                 case\n" +
                "                   when 综判码 != '4' and 产品规范 != 原产品规范 and 原产品规范 != ' ' and\n" +
                "                        substr(缺陷代码, 0, 1) = 'L' then\n" +
                "                    重量\n" +
                "                   else\n" +
                "                    0\n" +
                "                 end 热处理改判量,\n" +
                "                 case\n" +
                "                   when 综判码 != '4' and 产品规范 != 原产品规范 and 原产品规范 != ' ' and\n" +
                "                        (缺陷代码 = 'H800' or 缺陷代码 = '@@') then\n" +
                "                    重量\n" +
                "                   else\n" +
                "                    0\n" +
                "                 end 性能改判量,\n" +
                "                 case\n" +
                "                   when (综判码 = '4' and 综判时间 = ' ') or 封锁注释 = '轧废' then\n" +
                "                    重量\n" +
                "                   else\n" +
                "                    0\n" +
                "                 end 轧废废品,\n" +
                "                 0 H开头废品,\n" +
                "                 case\n" +
                "                   when 综判码 != '4' and (产品规范 = 原产品规范 or 原产品规范 = ' ') and\n" +
                "                        合同厚度 = 材料厚度 and 合同宽下限 <= 材料宽度 and 合同宽上限 >= 材料宽度 and\n" +
                "                        合同长下限 <= 材料长度 and 合同长上限 >= 材料长度 then\n" +
                "                    重量\n" +
                "                   else\n" +
                "                    0\n" +
                "                 end 计划品,\n" +
                "                 case\n" +
                "                   when 综判码 != '4' and (产品规范 = 原产品规范 or 原产品规范 = ' ') AND\n" +
                "                        封锁注释 != '轧废' and\n" +
                "                        (合同厚度 != 材料厚度 or 合同宽下限 > 材料宽度 or 合同宽上限 < 材料宽度 or\n" +
                "                        合同长下限 > 材料长度 or 合同长上限 < 材料长度) then\n" +
                "                    重量\n" +
                "                   else\n" +
                "                    0\n" +
                "                 end 非计划品,\n" +
                "                 case\n" +
                "                   when 综判码 != '4' and (产品规范 = 原产品规范 or 原产品规范 = ' ') and\n" +
                "                        (合同厚度 != 材料厚度) then\n" +
                "                    重量\n" +
                "                   else\n" +
                "                    0\n" +
                "                 end 厚度非计划品,\n" +
                "                 case\n" +
                "                   when 综判码 != '4' and (产品规范 = 原产品规范 or 原产品规范 = ' ') and\n" +
                "                        (合同宽下限 > 材料宽度 or 合同宽上限 < 材料宽度) then\n" +
                "                    重量\n" +
                "                   else\n" +
                "                    0\n" +
                "                 end 宽度非计划品,\n" +
                "                 case\n" +
                "                   when 综判码 != '4' and (产品规范 = 原产品规范 or 原产品规范 = ' ') and\n" +
                "                        (合同长下限 > 材料长度 or 合同长上限 < 材料长度) then\n" +
                "                    重量\n" +
                "                   else\n" +
                "                    0\n" +
                "                 end 长度非计划品,\n" +
                "                 0 定尺协议量,\n" +
                "                 0 定尺废品,\n" +
                "                 产出重量,\n" +
                "                 case\n" +
                "                   when (实际厚度 - 材料厚度) < 0 then\n" +
                "                    1\n" +
                "                   else\n" +
                "                    0\n" +
                "                 end 负偏差块数,\n" +
                "                 case\n" +
                "                   when (实际厚度 - 材料厚度) >= 0 then\n" +
                "                    1\n" +
                "                   else\n" +
                "                    0\n" +
                "                 end 正偏差块数,\n" +
                "                 1 块数合计,\n" +
                "                 实际厚度 - 材料厚度 负偏差和,\n" +
                "                 case\n" +
                "                   when 综判码 != '4' and (产品规范 = 原产品规范 or 原产品规范 = ' ') and\n" +
                "                        (合同厚度 != 材料厚度 or 合同宽下限 > 材料宽度 or 合同宽上限 < 材料宽度 or\n" +
                "                        合同长下限 > 材料长度 or 合同长上限 < 材料长度) and 缺陷代码 = 'H700' then\n" +
                "                    重量\n" +
                "                   else\n" +
                "                    0\n" +
                "                 end 合同变更量,\n" +
                "                 case\n" +
                "                   when 综判码 != '4' and 产品规范 != 原产品规范 and 原产品规范 != ' ' and\n" +
                "                        缺陷代码 = 'H700' then\n" +
                "                    重量\n" +
                "                   else\n" +
                "                    0\n" +
                "                 end 合同变更改判量,\n" +
                "                 case\n" +
                "                   when 合同宽上限 = 合同宽下限 and 合同长上限 = 合同长下限 then\n" +
                "                    '双定'\n" +
                "                   when (合同宽上限 = 合同宽下限 and 合同长上限 != 合同长下限) or\n" +
                "                        (合同宽上限 != 合同宽下限 and 合同长上限 = 合同长下限) then\n" +
                "                    '单定'\n" +
                "                   when 合同宽上限 != 合同宽下限 and 合同长上限 != 合同长下限 then\n" +
                "                    '非定'\n" +
                "                 end 定尺类型\n" +
                "            from V_tmrp04\n" +
                "          union all\n" +
                "          select 材料号,\n" +
                "                 产线,\n" +
                "                 计划牌号,\n" +
                "                 实际牌号,\n" +
                "                 内部钢种,\n" +
                "                 班组,\n" +
                "                 坯料厚度,\n" +
                "                 材料厚度,\n" +
                "                 实际厚度,\n" +
                "                 材料宽度,\n" +
                "                 材料长度,\n" +
                "                 切边标记,\n" +
                "                 边缘状态,\n" +
                "                 标准牌号代码,\n" +
                "                 厚度公差类别,\n" +
                "                 大板号,\n" +
                "                 板坯重量,\n" +
                "                 可用材代码 缺陷代码,\n" +
                "                 0 利用板量,\n" +
                "                 case\n" +
                "                   when 可利用材区分 = 'S' then\n" +
                "                    可用材重量\n" +
                "                   else\n" +
                "                    0\n" +
                "                 end 利用小板量,\n" +
                "                 case\n" +
                "                   when 可利用材区分 = 'Q' then\n" +
                "                    可用材重量\n" +
                "                   else\n" +
                "                    0\n" +
                "                 end 短尺板量,\n" +
                "                 case\n" +
                "                   when substr(可用材代码, 0, 1) = 'I' then\n" +
                "                    可用材重量\n" +
                "                   else\n" +
                "                    0\n" +
                "                 end 钢质协议量,\n" +
                "                 case\n" +
                "                   when (substr(可用材代码, 0, 1) = 'H' or\n" +
                "                        substr(可用材代码, 0, 1) = 'K') and 可用材代码 != 'H150' then\n" +
                "                    可用材重量\n" +
                "                   else\n" +
                "                    0\n" +
                "                 end 轧制协议量,\n" +
                "                 case\n" +
                "                   when substr(可用材代码, 0, 1) = 'L' then\n" +
                "                    可用材重量\n" +
                "                   else\n" +
                "                    0\n" +
                "                 end 热处理协议量,\n" +
                "                 0 性能协议量,\n" +
                "                 0 钢质废品,\n" +
                "                 0 轧制废品,\n" +
                "                 0 热处理废品,\n" +
                "                 0 多余废品量1,\n" +
                "                 0 多余废品量2,\n" +
                "                 0 钢质改判量,\n" +
                "                 0 轧制改判量,\n" +
                "                 0 热处理改判量,\n" +
                "                 0 性能改判量,\n" +
                "                 0 轧废废品,\n" +
                "                 0 H开头废品,\n" +
                "                 0 计划品,\n" +
                "                 0 非计划品,\n" +
                "                 0 厚度非计划品,\n" +
                "                 0 宽度非计划品,\n" +
                "                 0 长度非计划品,\n" +
                "                 case\n" +
                "                   when 可用材代码 = 'H150' then\n" +
                "                    可用材重量\n" +
                "                   else\n" +
                "                    0\n" +
                "                 end 定尺协议量,\n" +
                "                 0 定尺废品,\n" +
                "                 0 产出重量,\n" +
                "                 0 负偏差块数,\n" +
                "                 0 正偏差块数,\n" +
                "                 0 块数合计,\n" +
                "                 0 负偏差和,\n" +
                "                 0 合同变更量,\n" +
                "                 0 合同变更改判量,\n" +
                "                 case\n" +
                "                   when 合同宽上限 = 合同宽下限 and 合同长上限 = 合同长下限 then\n" +
                "                    '双定'\n" +
                "                   when (合同宽上限 = 合同宽下限 and 合同长上限 != 合同长下限) or\n" +
                "                        (合同宽上限 != 合同宽下限 and 合同长上限 = 合同长下限) then\n" +
                "                    '单定'\n" +
                "                   when 合同宽上限 != 合同宽下限 and 合同长上限 != 合同长下限 then\n" +
                "                    '非定'\n" +
                "                 end 定尺类型\n" +
                "            from V_tmrp01\n" +
                "          union all\n" +
                "          select 材料号,\n" +
                "                 产线,\n" +
                "                 计划牌号,\n" +
                "                 实际牌号,\n" +
                "                 内部钢种,\n" +
                "                 班组,\n" +
                "                 坯料厚度,\n" +
                "                 材料厚度,\n" +
                "                 实际厚度,\n" +
                "                 材料宽度,\n" +
                "                 材料长度,\n" +
                "                 切边标记,\n" +
                "                 边缘状态,\n" +
                "                 标准牌号代码,\n" +
                "                 厚度公差类别,\n" +
                "                 大板号,\n" +
                "                 板坯重量,\n" +
                "                 多余废品1代码 缺陷代码,\n" +
                "                 0 利用板量,\n" +
                "                 0 利用小板量,\n" +
                "                 0 短尺板量,\n" +
                "                 0 钢质协议量,\n" +
                "                 0 轧制协议量,\n" +
                "                 0 热处理协议量,\n" +
                "                 0 性能协议量,\n" +
                "                 case\n" +
                "                   when substr(多余废品1代码, 0, 1) = 'I' then\n" +
                "                    多余废品1重量\n" +
                "                   else\n" +
                "                    0\n" +
                "                 end 钢质废品,\n" +
                "                 case\n" +
                "                   when (substr(多余废品1代码, 0, 1) = 'H' or\n" +
                "                        substr(多余废品1代码, 0, 1) = 'K') and 多余废品1代码 != 'H140' then\n" +
                "                    多余废品1重量\n" +
                "                   else\n" +
                "                    0\n" +
                "                 end 轧制废品,\n" +
                "                 case\n" +
                "                   when substr(多余废品1代码, 0, 1) = 'L' then\n" +
                "                    多余废品1重量\n" +
                "                   else\n" +
                "                    0\n" +
                "                 end 热处理废品,\n" +
                "                 多余废品1重量 多余废品量1,\n" +
                "                 0 多余废品量2,\n" +
                "                 0 钢质改判量,\n" +
                "                 0 轧制改判量,\n" +
                "                 0 热处理改判量,\n" +
                "                 0 性能改判量,\n" +
                "                 0 轧废废品,\n" +
                "                 case\n" +
                "                   when substr(多余废品1代码, 0, 1) = 'H' then\n" +
                "                    多余废品1重量\n" +
                "                   else\n" +
                "                    0\n" +
                "                 end H开头废品,\n" +
                "                 0 计划品,\n" +
                "                 0 非计划品,\n" +
                "                 0 厚度非计划品,\n" +
                "                 0 宽度非计划品,\n" +
                "                 0 长度非计划品,\n" +
                "                 0 定尺协议量,\n" +
                "                 case\n" +
                "                   when 多余废品1代码 = 'H140' then\n" +
                "                    多余废品1重量\n" +
                "                   else\n" +
                "                    0\n" +
                "                 end 定尺废品,\n" +
                "                 0 产出重量,\n" +
                "                 0 负偏差块数,\n" +
                "                 0 正偏差块数,\n" +
                "                 0 块数合计,\n" +
                "                 0 负偏差和,\n" +
                "                 0 合同变更量,\n" +
                "                 0 合同变更改判量,\n" +
                "                 case\n" +
                "                   when 合同宽上限 = 合同宽下限 and 合同长上限 = 合同长下限 then\n" +
                "                    '双定'\n" +
                "                   when (合同宽上限 = 合同宽下限 and 合同长上限 != 合同长下限) or\n" +
                "                        (合同宽上限 != 合同宽下限 and 合同长上限 = 合同长下限) then\n" +
                "                    '单定'\n" +
                "                   when 合同宽上限 != 合同宽下限 and 合同长上限 != 合同长下限 then\n" +
                "                    '非定'\n" +
                "                 end 定尺类型\n" +
                "            from V_tmrp02\n" +
                "          union all\n" +
                "          select 材料号,\n" +
                "                 产线,\n" +
                "                 计划牌号,\n" +
                "                 实际牌号,\n" +
                "                 内部钢种,\n" +
                "                 班组,\n" +
                "                 坯料厚度,\n" +
                "                 材料厚度,\n" +
                "                 实际厚度,\n" +
                "                 材料宽度,\n" +
                "                 材料长度,\n" +
                "                 切边标记,\n" +
                "                 边缘状态,\n" +
                "                 标准牌号代码,\n" +
                "                 厚度公差类别,\n" +
                "                 大板号,\n" +
                "                 板坯重量,\n" +
                "                 多余废品2代码 缺陷代码,\n" +
                "                 0 利用板量,\n" +
                "                 0 利用小板量,\n" +
                "                 0 短尺板量,\n" +
                "                 0 钢质协议量,\n" +
                "                 0 轧制协议量,\n" +
                "                 0 热处理协议量,\n" +
                "                 0 性能协议量,\n" +
                "                 case\n" +
                "                   when substr(多余废品2代码, 0, 1) = 'I' then\n" +
                "                    多余废品2重量\n" +
                "                   else\n" +
                "                    0\n" +
                "                 end 钢质废品,\n" +
                "                 case\n" +
                "                   when (substr(多余废品2代码, 0, 1) = 'H' or\n" +
                "                        substr(多余废品2代码, 0, 1) = 'K') and 多余废品2代码 != 'H140' then\n" +
                "                    多余废品2重量\n" +
                "                   else\n" +
                "                    0\n" +
                "                 end 轧制废品,\n" +
                "                 case\n" +
                "                   when substr(多余废品2代码, 0, 1) = 'L' then\n" +
                "                    多余废品2重量\n" +
                "                   else\n" +
                "                    0\n" +
                "                 end 热处理废品,\n" +
                "                 0 多余废品量1,\n" +
                "                 多余废品2重量 多余废品量2,\n" +
                "                 0 钢质改判量,\n" +
                "                 0 轧制改判量,\n" +
                "                 0 热处理改判量,\n" +
                "                 0 性能改判量,\n" +
                "                 0 轧废废品,\n" +
                "                 case\n" +
                "                   when substr(多余废品2代码, 0, 1) = 'H' then\n" +
                "                    多余废品2重量\n" +
                "                   else\n" +
                "                    0\n" +
                "                 end H开头废,\n" +
                "                 0 计划品,\n" +
                "                 0 非计划品,\n" +
                "                 0 厚度非计划品,\n" +
                "                 0 宽度非计划品,\n" +
                "                 0 长度非计划品,\n" +
                "                 0 定尺协议量,\n" +
                "                 case\n" +
                "                   when 多余废品2代码 = 'H140' then\n" +
                "                    多余废品2重量\n" +
                "                   else\n" +
                "                    0\n" +
                "                 end 定尺废品,\n" +
                "                 0 产出重量,\n" +
                "                 0 负偏差块数,\n" +
                "                 0 正偏差块数,\n" +
                "                 0 块数合计,\n" +
                "                 0 负偏差和,\n" +
                "                 0 合同变更量,\n" +
                "                 0 合同变更改判量,\n" +
                "                 case\n" +
                "                   when 合同宽上限 = 合同宽下限 and 合同长上限 = 合同长下限 then\n" +
                "                    '双定'\n" +
                "                   when (合同宽上限 = 合同宽下限 and 合同长上限 != 合同长下限) or\n" +
                "                        (合同宽上限 != 合同宽下限 and 合同长上限 = 合同长下限) then\n" +
                "                    '单定'\n" +
                "                   when 合同宽上限 != 合同宽下限 and 合同长上限 != 合同长下限 then\n" +
                "                    '非定'\n" +
                "                 end 定尺类型\n" +
                "            from V_tmrp03)\n" +
                "    left join tqmtmts01\n" +
                "      on st_no = 内部钢种),\n" +
                "V_tmrpa2 as\n" +
                " (select 大板号 板号,\n" +
                "         max(产出重量) + sum(利用小板量 + 短尺板量) + sum(废品量) 分母量\n" +
                "    from V_tmrpa1\n" +
                "   group by 大板号)\n" +
                "   \n" +
                "select V_tmrpa1.*,\n" +
                "       SG_SIGN_BIG_CLASS 牌号大类,\n" +
                "       SG_SIGN_CLASS 牌号类别,\n" +
                "       PRODUCT_ALIAS 品种别名,\n" +
                "       分母量,\n" +
                "       case\n" +
                "         when substr(代码, 0, 1) = 'I' then\n" +
                "          非计划品\n" +
                "         else\n" +
                "          0\n" +
                "       end 钢质原因非定尺量,\n" +
                "       round((合格量 + 废品量) / 分母量 * 板坯重量, 3) 板坯量,\n" +
                "       round((合格量 + 废品量 - 钢质废品) / 分母量 * 板坯重量, 3) 投料量,\n" +
                "       case\n" +
                "         when 合格量 = '0' and 钢质废品 = '0' then\n" +
                "          round((合格量 + 废品量 - 钢质废品) / 分母量 * 板坯重量, 3)\n" +
                "         else\n" +
                "          round(((合格量 + 废品量 - 钢质废品) / 分母量 * 板坯重量) *\n" +
                "                (1 - (钢质废品 + 钢质协议量) / (合格量 + 钢质废品)),\n" +
                "                3)\n" +
                "       end 投料量1,\n" +
                "       round((协议量) / 分母量 * 板坯重量, 3) 协议投料量,\n" +
                "       round((改判量) / 分母量 * 板坯重量, 3) 改判投料量,\n" +
                "       round((废品量 - 钢质废品) / 分母量 * 板坯重量, 3) 废品投料量,\n" +
                "       轧制协议量 + 性能协议量 + 轧制改判量 + 性能改判量 轧制改判让步才率分子,\n" +
                "       合格量 - (case\n" +
                "         when substr(代码, 0, 1) = 'I' then\n" +
                "          非计划品\n" +
                "         else\n" +
                "          0\n" +
                "       end) 定尺率1分母,\n" +
                "       合格量 - 协议量 成材率1分子,\n" +
                "       钢质协议量 + 钢质改判量 钢质协议改判率分子,\n" +
                "       计划品 轧制命中率分子,\n" +
                "       计划品 + 非计划品 轧制命中率1分子,\n" +
                "       DECODE(BASE_OK_CHANCE, ' ', 0, BASE_OK_CHANCE) *\n" +
                "       DECODE(合格量, ' ', 0, 合格量) / 100 计划成材率分子,\n" +
                "       检验量 - 钢质改判量 - 钢质协议量 - 定尺协议量 - 定尺废品 轧制命中率分母,\n" +
                "       实际厚度 * (合格量) 平均厚度中间\n" +
                "  from V_tmrpa1\n" +
                "  left join V_tmrpa2\n" +
                "    on 大板号 = 板号\n" +
                "  left join TMMHP_SG_SIGN_INFO\n" +
                "    on 标准牌号代码 = SG_SIGN_CODE\n";

        PlainSelect plainSelect = getPlainSelect(sql2);
        List<Join> joins = plainSelect.getJoins();
        Table fromItem = (Table) plainSelect.getFromItem();
        System.out.println(fromItem.toString());
        Map<String, String> tableName = new HashMap<>();
        parseTableName(fromItem,tableName);
        //不需要别名
        if (joins != null) {
            for (Join join : joins) {
                fromItem = (Table) join.getRightItem();
                parseTableName(fromItem,tableName);
            }
        }
        int index = 1;
        List<ColMappingDto> colMappingDtos = new ArrayList<>();
        List<SelectItem> selectItems = plainSelect.getSelectItems();
        for (SelectItem selectItem : selectItems) {
            ColMappingDto colMapping = new ColMappingDto();
            SelectExpressionItem selectExpressionItem = (SelectExpressionItem)selectItem;
            if(selectExpressionItem.getAlias() != null){
                colMapping.setAlias(selectExpressionItem.getAlias().getName());
            }
            colMapping.setTable(fromItem.getName());
            if(selectExpressionItem.getExpression() instanceof Function){
                Function function = (Function) selectExpressionItem.getExpression();
                colMapping.setFunctionName("Function");
                if(colMapping.getAlias() == null){
                    String fn = function.getASTNode().jjtGetFirstToken().toString();
                    colMapping.setName(fn.toLowerCase()+"_"+index);
                    colMapping.setAlias(colMapping.getName());
                    index++;
                }else{
                    colMapping.setName(colMapping.getAlias());
                }
            }else {
                Column column = (Column) selectExpressionItem.getExpression();
                if(tableName.size() != 1){
                    if(column.getTable() == null){
                        throw new RuntimeException("SQL解析异常，字段["+column.getColumnName()+"]未设置表！");
                    }
                    colMapping.setTable(column.getTable().toString());
                }

                colMapping.setName(column.getColumnName());
                if(colMapping.getAlias() == null){
                    colMapping.setAlias(column.getColumnName());
                }
                colMapping.setFunctionName("Column");
            }
            colMappingDtos.add(colMapping);
        }
        System.out.println("21312");
        System.out.println(colMappingDtos);
       /* NormalSqlStructureDto normalSqlStructureDto = getStructure(sql2, true);
        normalSqlStructureDto.getColMappings().forEach(System.out::println);

        TableNameAndField tableNameAndField = parseTableNameAndField(sql2);
        System.out.println(tableNameAndField);
        NormalSqlStructureDto normalSqlStructureDto2 = getStructure(sql.replace("\r", " ").replace("\n", " "), true);

        System.out.println(normalSqlStructureDto2);*/
        //normalSqlStructureDto.getTableNames().forEach(System.out::println);
        //System.out.println("===============================================");
        //normalSqlStructureDto.getSelectItems().forEach(System.out::println);
        //1、获取所有表
        //2、获取所有表对应的字段
        //3、如果表的长度是1 ，将所有table设置为table
        //4、如果表的长度大于1，所有表必须有关联上，否则报错那个字段没有指定table

       /* System.out.println("===============================================");
        Select select = (Select) CCJSqlParserUtil.parse(sql2);
        PlainSelect plainSelect = (PlainSelect) select.getSelectBody();
        List<SelectItem> selectItems = plainSelect.getSelectItems();
        selectItems.forEach(System.err::println);*/
    }

    private static void parseTableName(Table names, Map<String, String> map) {
        Alias alias = names.getAlias();
        if(alias != null){
            map.put(alias.getName(),names.getName());
        }else{
            map.put(names.getName(),names.getName());
        }
    }

    /**
     * 构建表名和表别名的对应关系
     *
     * @param tableMapping
     * @param tableThemeMapping
     * @param sql
     * @param tblAlias
     */
    private static void buildTblMapping(Map<String, String> tableMapping, Map<String, String> tableThemeMapping, String sql, String tblAlias) {
        if (StringUtils.isNotEmpty(tblAlias)) {
            if (CollectionUtils.isEmpty(tableMapping) || Objects.isNull(tableMapping.get(tblAlias))) {
                sql = sql.replaceAll("(?i)\\s+as\\s+", " ");
                String regex = "(from|join)\\s+(\\w+\\.)?\\w+\\s+".concat(tblAlias).concat("\\s+");
                Pattern p = Pattern.compile(regex, Pattern.CASE_INSENSITIVE);
                Matcher m = p.matcher(sql.replaceAll("[\n\r]", " "));
                String replaceReg = "(?i)(from|join|" + tblAlias + ")";
                while (m.find()) {
                    tableMapping.put(tblAlias, m.group(0).replaceAll(replaceReg, "").trim());
                    tableThemeMapping.put(m.group(0).replaceAll(replaceReg, "").trim(), tblAlias);
                }
            }
        }
    }

    public static TableNameAndField parseTableNameAndField(String sql) {
        if (StringUtils.isEmpty(sql)) {
            throw new RuntimeException("请先输入SQL语句");
        }

        TableNameAndField tableNameAndField = new TableNameAndField();
        sql = sql.replace("\r", " ").replace("\n", " ").replaceAll("(\\$\\{\\w*\\})|(\\{\\{\\w+\\}\\})", "''");

        try {
            tableNameAndField.setTableNames(new TablesNamesFinder().getTableList(new CCJSqlParserManager().parse(new StringReader(sql))));
            Select select = (Select) CCJSqlParserUtil.parse(sql);
            PlainSelect plainSelect = (PlainSelect) select.getSelectBody();
            List<SelectItem> selectItems = plainSelect.getSelectItems();
            for (SelectItem selectItem : selectItems) {
                String field = selectItem.toString().replace("'", "").replace("\"", "").replace("`", "").toUpperCase();
                String[] fields = field.split(" AS ");
                //这里可能使用空格或者没有重命名情况
                if (fields.length == 1) {
                    fields = field.split(" ");
                    if (fields.length == 2) {

                    }
                } else {

                }
                StringBuilder stringBuilder = new StringBuilder();

                for (char c : field.toCharArray()) {

                }
                System.out.println(field);
            }
        } catch (JSQLParserException e) {
            throw new RuntimeException(e);
        }
        return tableNameAndField;
    }

    public static PlainSelect  getPlainSelect(String sql) {
        NormalSqlStructureDto normalSqlStructureDto = new NormalSqlStructureDto();
        if (StringUtils.isEmpty(sql)) {
            throw new RuntimeException("请先输入SQL语句");
        }
        normalSqlStructureDto.setSql(sql);
        sql = sql.replace("\r", " ").replace("\n", " ").replaceAll("(\\$\\{\\w*\\})|(\\{\\{\\w+\\}\\})", "''");
        // 1.解析表名
        CCJSqlParserManager parserManager = new CCJSqlParserManager();
        // 解析SQL为Statement对象
        Statement statement = null;
        try {
            statement = parserManager.parse(new StringReader(sql));
        } catch (JSQLParserException e) {
            throw new RuntimeException("SQL解析异常！");
        }
        return (PlainSelect) ((Select) statement).getSelectBody();
    }

    public static NormalSqlStructureDto getStructure(String sql){
        NormalSqlStructureDto normalSqlStructureDto = new NormalSqlStructureDto();
        normalSqlStructureDto.setSql(sql);
        PlainSelect plainSelect = getPlainSelect(sql);
        List<Join> joins = plainSelect.getJoins();
        Table fromItem = (Table) plainSelect.getFromItem();
        Map<String, String> tableName = new HashMap<>();
        parseTableName(fromItem,tableName);

        List<String> columnList = new ArrayList<>();
        List<String> tableNames = new ArrayList<>();
        //不需要别名
        if (joins != null) {
            for (Join join : joins) {
                fromItem = (Table) join.getRightItem();
                parseTableName(fromItem,tableName);
            }
        }
        normalSqlStructureDto.setTableThemeMappings(tableName);
        for (String value : tableName.values()) {
            tableNames.add(value);
        }
        normalSqlStructureDto.setTableNames(tableNames);
        int index = 1;
        List<ColMappingDto> colMappingDtos = new ArrayList<>();
        List<SelectItem> selectItems = plainSelect.getSelectItems();
        for (SelectItem selectItem : selectItems) {
            ColMappingDto colMapping = new ColMappingDto();
            SelectExpressionItem selectExpressionItem = (SelectExpressionItem)selectItem;
            if(selectExpressionItem.getAlias() != null){
                colMapping.setAlias(selectExpressionItem.getAlias().getName());
            }
            colMapping.setTable(fromItem.getName());
            if(selectExpressionItem.getExpression() instanceof Function){
                Function function = (Function) selectExpressionItem.getExpression();
                colMapping.setFunctionName("Function");
                if(colMapping.getAlias() == null){
                    String fn = function.getASTNode().jjtGetFirstToken().toString();
                    colMapping.setName(fn.toLowerCase()+"_"+index);
                    colMapping.setAlias(colMapping.getName());
                    index++;
                }else{
                    colMapping.setName(colMapping.getAlias());
                }
            }else {
                Column column = (Column) selectExpressionItem.getExpression();
                if(tableName.size() != 1){
                    if(column.getTable() == null){
                        throw new RuntimeException("SQL解析异常，字段["+column.getColumnName()+"]未设置表！");
                    }
                    colMapping.setTable(column.getTable().toString());
                }

                colMapping.setName(column.getColumnName());
                if(colMapping.getAlias() == null){
                    colMapping.setAlias(column.getColumnName());
                }
                colMapping.setFunctionName("Column");
            }
            columnList.add(colMapping.getName());
            colMappingDtos.add(colMapping);
        }
        normalSqlStructureDto.setColMappings(colMappingDtos);
        return normalSqlStructureDto;
    }
    /**
     * 解析sql结构
     *
     * @param sql
     * @param isAlias true|false 是否使用别称<br> eg. 【s_id as id】 => 【id】<br>
     * @return
     * @throws JSQLParserException
     */
    public static NormalSqlStructureDto getStructure(String sql, boolean isAlias) throws JSQLParserException {
        NormalSqlStructureDto normalSqlStructureDto = new NormalSqlStructureDto();
        if (StringUtils.isEmpty(sql)) {
            throw new RuntimeException("请先输入SQL语句");
        }
        normalSqlStructureDto.setSql(sql);
        sql = sql.replace("\r", " ").replace("\n", " ").replaceAll("(\\$\\{\\w*\\})|(\\{\\{\\w+\\}\\})", "''");
        // 1.解析表名
        CCJSqlParserManager parserManager = new CCJSqlParserManager();
        // 解析SQL为Statement对象
        Statement statement = parserManager.parse(new StringReader(sql));
        // 创建表名发现者对象
        TablesNamesFinder tablesNamesFinder = new TablesNamesFinder();
        // 获取到表名列表
        List<String> tableNameList = tablesNamesFinder.getTableList(statement);
        normalSqlStructureDto.setTableNames(tableNameList);
        // 表别名映射
        Map<String, String> tableMapping = new HashMap<>();
        Map<String, String> tableThemeMapping = new HashMap<>();
        tableNameList.forEach(i -> {
            tableMapping.put(i, i);
            tableThemeMapping.put(i, i);
        });
        // 字段和表的映射
        List<ColMappingDto> colMappingList = new ArrayList<>();

        // 2.解析查询元素 列，函数等
        Select select = (Select) CCJSqlParserUtil.parse(sql);
        PlainSelect plainSelect = (PlainSelect) select.getSelectBody();
        /*FromItem fromItem = plainSelect.getFromItem();
        System.out.println(JSON.toJSON(fromItem).toString());
        fromItem.getAlias();*/

        List<SelectItem> selectItems = plainSelect.getSelectItems();
        List<String> columnList = new ArrayList<>();
        if (!CollectionUtils.isEmpty(selectItems)) {
            for (SelectItem selectItem : selectItems) {
                ColMappingDto colMapping = new ColMappingDto();
                String columnName = null;
                String tblAlias = null;
                try {
                    if (selectItem instanceof SelectExpressionItem) {
                        SelectExpressionItem selectExpressionItem = (SelectExpressionItem) selectItem;
                        Alias alias = selectExpressionItem.getAlias();
                        Expression expression = selectExpressionItem.getExpression();
                        colMapping.setFunctionName(expression.getASTNode().toString());
                        if (alias != null) {
                            tblAlias = alias.getName();
                        }
                        Column col = ((Column) expression);
                        buildTblMapping(tableMapping, tableThemeMapping, sql, tblAlias);
                        if (!isAlias) {
                            columnName = selectItem.toString();
                        } else if (expression instanceof CaseExpression) {
                            // case表达式
                            columnName = alias.getName();
                        } else if (expression instanceof LongValue || expression instanceof StringValue || expression instanceof DateValue || expression instanceof DoubleValue) {
                            // 值表达式
                            columnName = Objects.nonNull(alias.getName()) ? alias.getName() : expression.getASTNode().jjtGetValue().toString();
                        } else if (expression instanceof TimeKeyExpression) {
                            // 日期
                            columnName = alias.getName();
                        } else {
                            if (alias != null) {
                                columnName = alias.getName();
                            } else {
                                SimpleNode node = expression.getASTNode();
                                Object value = node.jjtGetValue();
                                if (value instanceof Column) {
                                    columnName = ((Column) value).getColumnName();
                                } else if (value instanceof Function) {
                                    columnName = value.toString();
                                } else {
                                    // 增加对select 'aaa' from table; 的支持
                                    columnName = String.valueOf(value);
                                    columnName = columnName.replace("'", "");
                                    columnName = columnName.replace("\"", "");
                                    columnName = columnName.replace("`", "");
                                }
                            }
                        }

                        columnName = columnName.replace("'", "");
                        columnName = columnName.replace("\"", "");
                        columnName = columnName.replace("`", "");

                        colMapping.setName(col.getColumnName());

                        Table colTbl = col.getTable();
                        if (Objects.nonNull(colTbl)) {
                            tblAlias = colTbl.getName();
                        } else if (tableNameList.size() == 1) {
                            tblAlias = tableNameList.get(0);
                        } else {
                            throw new RuntimeException("SQL解析异常，列[" + colMapping.getName() + "]未能找到对应表！");
                        }
                        if (Objects.nonNull(alias) && StringUtils.isNotEmpty(alias.getName())) {
                            colMapping.setAlias(alias.getName());
                        }
                        colMapping.setTable(tableMapping.get(tblAlias));

                    } else if (selectItem instanceof AllTableColumns) {
                        AllTableColumns allTableColumns = (AllTableColumns) selectItem;
                        columnName = allTableColumns.toString();
                        if (columnName.indexOf(".") > -1) {
                            tblAlias = columnName.substring(0, columnName.indexOf(".")).trim();
                            buildTblMapping(tableMapping, tableThemeMapping, sql, tblAlias);
                            colMapping.setTable(tableMapping.get(tblAlias));
                        }
                        colMapping.setName(columnName);
                    } else if (selectItem.toString().equals("*")) {
                        columnName = selectItem.toString();
                        colMapping.setName(columnName);
                        //colMapping.setTable(tableNameList);
                    } else {
                        columnName = selectItem.toString();
                        colMapping.setName(columnName);
                        colMapping.setType("varchar");
                    }
                } catch (Exception e) {
                    columnName = selectItem.toString();

                    colMapping.setName(columnName);
                    colMapping.setAlias(tblAlias);
                    colMapping.setType("varchar");
                    if (tableNameList.size() == 1) {
                        colMapping.setTable(tableNameList.get(0));
                    }

                }
                String[] columnNames = columnName.split("\\.");
                if (colMapping.getAlias() == null) {
                    if (columnNames.length == 2) {
                        colMapping.setAlias(columnNames[1]);
                    } else if (columnNames.length == 1) {
                        colMapping.setAlias(columnNames[0]);
                    }

                }
                columnList.add(columnName);
                colMappingList.add(colMapping);
            }
            normalSqlStructureDto.setSelectItems(columnList);
            normalSqlStructureDto.setColMappings(colMappingList);
            normalSqlStructureDto.setTableThemeMappings(tableThemeMapping);
        }
        return normalSqlStructureDto;
    }

}
